package core;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import configuration.CustomObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisException;

import java.util.Set;

/**
 * 存放向redis中保存数据，提取数据等的一些方法
 *
 */
@Component
@Slf4j
public class RedisTemplate {

    @Autowired
    private JedisPool jedisPool;

    @Autowired
    private CustomObjectMapper objectMapper;

    public String set(String key,String value,Long expire) {
        Jedis jedis = jedisPool.getResource();
        String result = null;
        try {
            result = jedis.setex(key, expire, value);
        } catch (JedisException e) {
            log.error("redis execution error",e);
            jedisPool.returnResource(jedis);
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    public String get(String key) {
        Jedis jedis = jedisPool.getResource();
        String result = null;
        try {
            result = jedis.get(key);
        } catch (JedisException e) {
            log.error("redis execution error",e);
            jedisPool.returnResource(jedis);
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    public String setObject(String key,Object value,Long expire) {
        Jedis jedis = jedisPool.getResource();
        String result = null;

        try {
            String jsonValue = objectMapper.writeValueAsString(value);
            if(expire <= 0) {
                result = jedis.set(key,jsonValue);
            }else {
                result = jedis.setex(key,expire,jsonValue);
            }
        } catch (JedisException | JsonProcessingException e) {
            log.error("redis execution error",e);
            jedisPool.returnResource(jedis);
        } finally {
            jedisPool.returnResource(jedis);
        }

        return result;
    }

    public <E> E getObject(String key, TypeReference<E> typeReference) {
        Jedis jedis = jedisPool.getResource();
        E e = null;
        try {
            String result = jedis.get(key);
            e = objectMapper.readValue(result,typeReference);
        }  catch (JedisException | JsonProcessingException ex) {
            log.error("redis execution error",ex);
            jedisPool.returnResource(jedis);
        } finally {
            jedisPool.returnResource(jedis);
        }
        return e;
    }

    public Long remove(String ... key) {
        Jedis jedis = jedisPool.getResource();
        Long result = 0L;
        try {
            result = jedis.del(key);
        } catch (Exception e) {
            log.error("redis exception error",e);
            jedisPool.returnResource(jedis);
        }finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    public Long expire(String key, Long expire) {
        Jedis jedis = jedisPool.getResource();
        Long exp = -1L;
        try {
            exp = jedis.expire(key,expire);
        }catch (Exception e) {
            log.error("redis execution error->" + e);
            jedisPool.returnResource(jedis);
        }finally {
            jedisPool.returnResource(jedis);
        }
        return exp;
    }

    public Set<String> keys(String regex) {
        Jedis jedis = jedisPool.getResource();
        Set<String> keys = null;
        try {
            keys = jedis.keys(regex);
        }catch (Exception e) {
            log.error("redis execution error->" + e);
            jedisPool.returnResource(jedis);
        }finally {
            jedisPool.returnResource(jedis);
        }
        return keys;
    }

}
